package org.common.utils.weight;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 权重操作处理
 * @author zhouzhibing
 * @date 2024/3/4
 */
public class Weights {

    /**
     * 根据权重，在列表中随机出一个对象数据。
     * @param weightList 根据指定map列表。
     * @param getWeight 获取getWeight权重值方式
     * @return 返回列表中随机出一个对象数据。
     * @param <T> 指定类型
     */
    public static <T> WeightResult<T> getRandomWeight(List<T> weightList , GetWeight<T> getWeight) {
        if(weightList == null || weightList.isEmpty())
            return null;

        if(weightList.size() == 1)
            return new WeightResult<T>(weightList.getFirst() , 0);

        int sum = 0 , w = 0;
        for (T object : weightList)
            sum += getWeight.getWeight(object);

        int randomNo = getRandomInt(0, sum - 1);
        sum = 0;

        for (int i = 0 , size = weightList.size(); i < size; i++) {
            T object = weightList.get(i);
            w = getWeight.getWeight(object);
            if(sum <= randomNo && randomNo < sum + w)
                return new WeightResult<T>(object , i);
            sum += w;
        }
        return null;
    }

    /**
     * @param min 最小值
     * @param max 最大值
     * @return 根据指定范围返回一个随机值（包括起始值和结束值）。
     */
    public static int getRandomInt(int min , int max ) {
        if(min < 0 || max < 0)
            throw new RuntimeException("Weights.getRandomInt min、max error , min:" + min + " max:" + max);

        if(min == max)
            return min;
        ThreadLocalRandom random = ThreadLocalRandom.current();
        return random.nextInt(min, max + 1);
    }

}
